package cn.uin.infrastructure.adapter.repository.common;

import cn.uin.domain.shared.adapter.repository.IPage;
import cn.uin.domain.shared.adapter.repository.IPageable;
import cn.uin.domain.shared.adapter.repository.ISort;
import org.springframework.data.domain.Sort;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @ClassName PageHelperPage
 * @Description:基于 PageHelper 的分页结果实现
 *              将 PageHelper 的 Page 对象适配为domain的 IPage 接口
 * @Author: Administrator
 * @CreateDate: 2025/11/14 17:49
 * @Version: 1.0
 */
public class PageHelperPage<T> implements IPage<T> {

	private final List<T> content;
	private final IPageable pageable;
	private final long total;

	/**
	 * 构造函数
	 * @param content 当前页数据内容
	 * @param pageable 分页请求信息
	 * @param total 总记录数
	 */
	public PageHelperPage(List<T> content, IPageable pageable, long total) {
		this.content = content != null ? Collections.unmodifiableList(new ArrayList<>(content)) : Collections.emptyList();
		this.pageable = pageable;
		this.total = total;
	}

	/**
	 * 从 PageHelper 的 Page 对象创建领域分页对象
	 * @param pageHelperPage PageHelper 的 Page 对象
	 * @param pageable 分页请求信息
	 * @param <T> 数据类型
	 * @return 领域分页对象
	 */
	public static <T> PageHelperPage<T> of(com.github.pagehelper.Page<T> pageHelperPage, IPageable pageable) {
		return new PageHelperPage<>(
				pageHelperPage.getResult(),
				pageable,
				pageHelperPage.getTotal()
		);
	}

	@Override
	public int getTotalPages() {
		return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize());
	}

	@Override
	public long getTotalElements() {
		return total;
	}

	@Override
	public int getNumber() {
		return pageable != null ? pageable.getPageNumber() : 0;
	}

	@Override
	public int getSize() {
		return pageable != null ? pageable.getPageSize() : content.size();
	}

	@Override
	public int getNumberOfElements() {
		return content.size();
	}

	@Override
	public List<T> getContent() {
		return Collections.unmodifiableList(content);
	}

	@Override
	public boolean hasContent() {
		return !content.isEmpty();
	}

	@Override
	public ISort getSort() {
		return pageable != null ? pageable.getSort() : ISort.unsorted();
	}

	@Override
	public boolean isFirst() {
		return !hasPrevious();
	}

	@Override
	public boolean isLast() {
		return !hasNext();
	}

	@Override
	public boolean hasNext() {
		return getNumber() + 1 < getTotalPages();
	}

	@Override
	public boolean hasPrevious() {
		return getNumber() > 0;
	}

	@Override
	public IPageable nextPageable() {
		return hasNext() ? pageable.next() : IPageable.of(getNumber(), getSize(), getSort());
	}

	@Override
	public IPageable previousPageable() {
		return hasPrevious() ? pageable.previousOrFirst() : IPageable.of(getNumber(), getSize(), getSort());
	}

	@Override
	public <U> IPage<U> map(Function<? super T, ? extends U> converter) {
		// Java 8 兼容的 Stream 操作
		List<U> convertedContent = content.stream()
				.map(converter)
				.collect(Collectors.toList());
		return new PageHelperPage<>(convertedContent, pageable, total);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (!(obj instanceof PageHelperPage)) return false;
		PageHelperPage<?> that = (PageHelperPage<?>) obj;
		return total == that.total &&
				content.equals(that.content) &&
				(pageable != null ? pageable.equals(that.pageable) : that.pageable == null);
	}

	@Override
	public int hashCode() {
		int result = content.hashCode();
		result = 31 * result + (pageable != null ? pageable.hashCode() : 0);
		result = 31 * result + (int) (total ^ (total >>> 32));
		return result;
	}

	@Override
	public String toString() {
		String contentType = "UNKNOWN";
		if (!content.isEmpty()) {
			contentType = content.get(0).getClass().getName();
		}
		return String.format("Page %d of %d containing %s instances",
				getNumber(), getTotalPages(), contentType);
	}

}
